<?php
/**
 * Logger
 *
 * @category	Log
 * @package		dayscript.log
 * @subpackage
 * @author		Nelson Daza <ndaza@dayscript.com>
 * @copyright	2009 Dayscript Ltda.
 * @license
 * @version		1.0
 * @version		$Revision: 0 $
 * @filesource
 * @link		http://www.dayscript.com
 * @link		{docsLink}
 * @uses
 * @since		1.0
 * @modifiedby	$LastChangedBy: Nelson Daza $
 * @modified	$Date: 2009-09-02 $
 */

namespace dayscript\log;

/**
 * Logger
 *
 * @category	Log
 * @package		dayscript.log
 * @subpackage
 * @author		Nelson Daza <ndaza@dayscript.com>
 * @copyright	2009 Dayscript Ltda.
 * @license
 * @version		1.0
 * @link		http://www.dayscript.com
 * @link		{docsLink}
 * @uses		\dayscript\Map
 * @since		1.0
 * @modifiedby	$LastChangedBy: Nelson Daza $
 * @modified	$Date: 2009-09-03 $
 */
abstract class Logger	{
	/**
	 * Log PHP errors. You can determine what php's information gets logged using global php constants like ( E_ALL | E_STRICT ) or 0 (cero) for no Logging.
	 * @var int $phpThreshold
	 */
	protected $phpThreshold = -1;
	/**
	 * Log APP errors. You can determine what application's/framework's information gets logged or 0 (cero) for no Logging.
	 * @var int $appThreshold
	 */
	protected $appThreshold = -1;
	/**
	 * Prepend to every each log message. Default "'[' . date( 'Y-m-d H:i:s' ) . '] '", used as an eval expresion.
	 * @var string $prepend
	 */
	protected $prepend = null;
	/**
	 * Append to every each log message. Default '', used as an eval expresion.
	 * @var string $append
	 */
	protected $append = null;
	/**
	 * Logger identificator
	 * @var string
	 */
	protected $name;
	/**
	 * Logger identificator
	 * @var string
	 */
	protected $config;
	/**
	 * Buffer for logs when no output has started.
	 * @var array
	 */
	protected $buffer = array( );
	/**
	 * Whether use buffer.
	 * @var boolean
	 */
	protected $useBuffer = true;
	/**
	 * Logger constructor
	 * @param string $name Logger identificator
	 * @param array|\dayscript\Map $config Logger configuration
	 * @return Logger
	 */
	public function __construct( $name, \dayscript\Map $config = null )	{
		$this->name = $name;
		$this->config = new \dayscript\Map( $config );
		
		$val = $this->config->get( 'php_threshold', -1 );
		if( \is_string( $val ) )
			$val = \bindec( $val );
		$this->phpThreshold = $val;
		
		$val = $this->config->get( 'app_threshold', -1 );
		if( \is_string( $val ) )
			$val = \bindec( $val );
		$this->appThreshold = $val;
		
		$this->prepend = $this->config->get( 'prepend', '"[" . $date . "] "' );
		$this->append = $this->config->get( 'append', "''" );
	}
	/**
	 * Returns actual Logger name
	 * @return string $name
	 */
	public final function getName( )	{
		return $this->name;
	}
	/**
	 * Sends actual log message direct to the output
	 * @param string $date Logging time
	 * @param string $message String to log
	 * @param $threshold {@see \dayscript\ErrorManager::$type }
	 * @param int|null $filterThreshold Filter threshold or null for error_reporting( ) use.
	 */
	public final function log( $date, $message, $threshold, $system, $filterThreshold = null )	{
		$this->store( $date, $message, $threshold, $system, $filterThreshold );
		$this->flush( );
	}
	/**
	 * Stores actual message in the logger buffer
	 * @param string $date Logging time
	 * @param string $message String to log
	 * @param $threshold {@see \dayscript\ErrorManager::$type }
	 * @param int|null $filterThreshold Filter threshold or null for error_reporting( ) use.
	 */
	public final function store( $date, $message, $threshold, $system, $filterThreshold = null )	{
		if( $filterThreshold === null )
			$filterThreshold = \error_reporting( );
		
		// Intersection between $threshold === 0 typically means production mode, in this case not all loggers will do its job.
		$actualThreshold = ( $system === true ? $this->phpThreshold : $this->appThreshold ) & $threshold;
		
		// $threshold === 0 typically means production mode, in this case not all loggers will do its job.
		// $filterThreshold === 0 typically means production mode but olso use of @.
		if( $actualThreshold !== 0 || $threshold === 0 )	{
			$prepend = '';
			@eval( '$prepend = ' . $this->prepend . ';' );
			$append = '';
			@eval( '$append = ' . $this->append . ';' );
			if( $actualThreshold & $filterThreshold )
				$this->buffer[] = \sprintf( "\n%s %s %s%s", $prepend, ( $system ? 'PHP' : 'APP' ), $message, $append );
		}
	}
	/**
	 * Flushes all pending messages.
	 */
	public abstract function flush( );
}